/*
    PhotoFlip, a free 3d photo managment suite.
    Copyright (C) 2007  Elisée MAURER, Gaétan WALTER
    
    This file is part of PhotoFlip.
    Contact: http://www.photoflip.org/

    PhotoFlip is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    PhotoFlip is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with PhotoFlip.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef GLAREA_HPP_INCLUDED
#define GLAREA_HPP_INCLUDED

#include <gtkmm.h>
#include <gtkglmm.h>

#include <vector>

#include "library.hpp"
#include "visualisation.hpp"
#include "dock.hpp"

//! GL drawing area widget, the Core of PhotoFlip
/*!
  It links OpenGL and GTK+, and is part of the core of the program.
*/
class GLArea: public Gtk::DrawingArea, public Gtk::GL::Widget<GLArea> {
	private:
		library *m_lib;
		visualisation *m_visu;
		
		dock m_dock;
		GLuint m_texIcons[MAX_ICONS];
		
		GLuint m_texCollectionThumbnails[MAX_COLLECTIONS];
		GLuint m_texFrames[MAX_FRAMES];
		GLuint m_texSelected;
		int m_lastFullPhoto, m_fullPhoto;
		Glib::RefPtr<Gdk::Pixbuf> m_pixFullPhoto;
		
		int m_clickedElement, m_mouseX, m_mouseY, m_clickX, m_clickY;
		int m_dragMode, m_draggedElement;
		bool m_clickedTwice, m_clickedThreeTimes;
		bool m_leftCtrl, m_rightCtrl, m_leftShift, m_rightShift;
		
		sigc::connection m_timer, m_slideshowTimer;
		Glib::Dispatcher m_dispPhotoLoaded;
		Gtk::Menu *m_popupMenuView, *m_popupMenuPhoto, *m_menuFrame;
		Gtk::RadioButtonGroup m_frameGroup;
	public:
		//! GLArea constructor.
		GLArea(library *lib);
		//! GLArea destructor.
		virtual ~GLArea();
		
		//! Signal called on key press / release
		bool on_key(GdkEventKey* event);
		void on_after(GdkEvent* event);
		
		//! Updates the pointer to current visualisation.
		void setVisualisation(visualisation *visu);
		//! Sets pointers to the (right-click popup) View, Photo an Frame menus.
		void setPopupMenus(Gtk::Menu *popupMenuView, Gtk::Menu *popupMenuPhoto, Gtk::Menu *menuFrame, Gtk::RadioButtonGroup frameGroup);
		//! Sets current photo's frame
		void setFrame(int frame);
		//! Sets whether to show photo frames or not.
		void showFrames(bool state = true);
		
		//! Loads a small thumbnail for each collection to be displayed inside photo cases in desktop view.
		void loadCollectionThumbnails();
		
		//! Loads a collection
		void loadCollection(int collection);
		//! Returns current element (collection or photo).
		int getElement();
		//! Sets current element (collection or photo) and starts the thread to load the full quality photo if applies.
		void setElement(int element);
		
		//! Loads full quality photo from file (this is called by setElement() as a new thread).
		void loadFullPhoto(std::string filename);
		//! Function signal called by dispatcher emitted by loadFullPhoto() on completion.
		void on_fullPhotoLoaded();
		
		//! Moves a photo to the basket
		void moveToBasket(int photo = -1);
		//! Copies a photo to the basket
		void copyToBasket(int photo = -1);
		
		//! Moves a photo from the basket
		void moveFromBasket(int basketPhoto);
		//! Copies a photo from the basket
		void copyFromBasket(int basketPhoto);
		
		void deletePhoto(int photo = -1);
		//void deletePhotoFromBasket(int basketPhoto);
		
		//! Sets zoom.
		void setZoom(float zoom);
		//! Gets current zoom.
		float getZoom();
	protected:
		//! Signal called on user mouse scrolling
		bool on_scroll(GdkEventScroll* event);
		//! Signal called on user mouse button press
		bool on_button_press(GdkEventButton* event);
		//! Signal called on user mouse button release
		bool on_button_release(GdkEventButton* event);
		//! Signal called on user mouse motion
		bool on_motion(GdkEventMotion* event);
		
		//! Regularly updates different PhotoFlip components.
		bool timer();
		//! Returns which object is under mouse cursor.
		int select(int x, int y);
		
		//! Redraws
		bool redraw();
		
		//! Widget realize signal.
		virtual void on_realize();
		//! Widget resize signal.
		virtual bool on_configure_event(GdkEventConfigure* event);
		//! Signal called when widget needs to be (re)drawn.
		virtual bool on_expose_event(GdkEventExpose* event);
};

#endif // GLAREA_HPP_INCLUDED
